home *** CD-ROM | disk | FTP | other *** search
- TITLE WHEREIS - FIND A FILE ON THE DRIVE
- PAGE 60,132
-
- IF1
- INCLUDE OPTMAC.LIB
- ENDIF
- GENOPT RHSVDA
- GENOPT LEG
- GENOPT NX
-
- ;-------------------------------------------------------------------------;
- ; This is the format for the DOS data transfer area used when DOS 2.0 ;
- ; searches for a file match in directories. ;
- ;-------------------------------------------------------------------------;
-
- DTA STRUC
- RESERVED DB 21 DUP(?)
- ATTRIBUTE DB ?
- TIME DW ?
- DATE DW ?
- SIZE DD ?
- NAMFOUND DB 13 DUP(?)
- DTA ENDS
-
- PAGE
- CR EQU 13
- LF EQU 10
- ;---------------------------------------------------------------------;
- ; This is the main program that sets up the initial conditions for ;
- ; SCHDIR which, in turn, does a recursive search. ;
- ; ;
- ; READS: PATNAME ;
- ; WRITES: FILNAME ;
- ; CALLS: SCHDIR ;
- ;---------------------------------------------------------------------;
- CODSEG SEGMENT
- ASSUME CS:CODSEG,DS:CODSEG
- ORG 100H
- WHEREIS PROC NEAR
- MOV AX,CS
- MOV SS,AX
- MOV SP,OFFSET LOCAL_STACK
- MOV DS,AX
- MOV ES,AX
- MOV BX,OFFSET LOCAL_STACK+15
- MOV CL,4
- SHR BX,CL
- MOV AH,4AH
- INT 21H
- JNC NOALCERR
- MOV DX,OFFSET MSG1
- MOV AH,9
- INT 21H
- INT 20H
- NOALCERR:
- MOV AH,25
- INT 21H
- ADD AL,'A'
- MOV PATNAME,AL
- MOV PATADR,OFFSET PATNAME+2
- MOV SI,81H ; start of command line
- BYPASSBLANKS:
- LODSB
- CMP AL,' '
- JZ BYPASSBLANKS
- MOV DI,OFFSET FILNAME
- CMP AL,0DH ; carriage return character?
- JE DONREADINNAME ; yes, end of name
- CMP AL,'/' ; slash character?
- JE DONREADINNAME ; yes, end of name
- MOV [DI],AL
- LODSB ; Get second character
- CMP AL,':'
- JZ GETDRV
- DEC SI
- DEC SI
- JMP SHORT GESEARCNAME
- GETDRV: MOV AL,[DI]
- MOV PATNAME,AL
- GESEARCNAME:
- LODSB ; get first character
- CMP AL,0DH ; carriage return character?
- JE DONREADINNAME ; yes, end of name
- CMP AL,'/' ; slash character?
- JE DONREADINNAME ; yes, end of name
- CMP AL,' ' ; space character?
- JE DONREADINNAME ; yes, end of name
- CMP AL,'\'
- JNE NOTBAD
- MOV DI,OFFSET FILNAME
- MOV DTAFLAG,0
- MOV DOTFLAG,0
- MOV EXTFLAG,0
- JMP GESEARCNAME
- NOTBAD:
- CMP AL,'.' ; Check for period in file name
- JNE NOTBAD1
- CMP DTAFLAG,0
- JNZ NOTBAD0A
- MOV BYTE PTR [DI],'*'
- INC DI
- NOTBAD0A:
- STOSB
- MOV DOTFLAG,AL ; Set for period in file name
- JMP GESEARCNAME
- NOTBAD1:
- STOSB
- CMP DOTFLAG,0
- JZ NOTBAD2
- MOV EXTFLAG,AL
- JMP GESEARCNAME
- NOTBAD2:
- MOV DTAFLAG,AL
- JMP GESEARCNAME
- DONREADINNAME:
- CMP AL,'/'
- JZ GOTOPT
- JMP NOTOPT
- GOTOPT: LODSB
- AND AL,5FH
- TESTOP RHSVDA,GOTA
- TESTOP LEG,GOTE
- TESTOP NX,GOTX
- CMP AL,'F'
- JZ GOTF
- CALL TSTVAL
- MOV AH,AL
- NXTLCT: LODSB
- CMP AL,'/'
- JZ SETLCT
- CMP AL,13
- JZ SETLCT
- CALL TSTVAL
- MOV BH,AH
- ADD AH,AH
- ADD AH,AH
- ADD AH,BH
- ADD AH,AH
- ADD AH,AL
- JMP NXTLCT
- SETLCT: MOV LINECT,AH
- MOV CURLIN,AH
- DEC SI
- JMP SHORT NEXTOPT
- BADOPT: MOV DX,OFFSET BOM1
- MOV AH,9
- INT 21H
- JMP ABSXIT
- GOTA: OR MYATTR,AH
- NEXTOPT:
- LODSB
- JMP DONREADINNAME
- GOTE: OR DFLAG,AH
- JMP NEXTOPT
- GOTX: OR OPFLAG,AH
- JMP NEXTOPT
- GOTF: MOV PATADR,OFFSET PATNAME
- JMP NEXTOPT
- BOM1 DB 'Bad option selected',CR,LF,'$'
- TSTVAL: DEC SI
- LODSB
- SUB AL,'0'
- JB BADOPT
- CMP AL,9
- JA BADOPT
- RET
- NOTOPT:
- CMP DFLAG,LOPT+EOPT+GOPT
- JNZ SETDATE
- MOV DFLAG,0
- JMP SHORT SNODATE
- SETDATE:
- CMP DOTFLAG,0
- JNZ GOTDOT
- CMP DTAFLAG,0
- JNZ GOTDTA
- MOV AL,'*'
- STOSB
- GOTDTA:
- MOV AX,'*.'
- STOSW
- GOTDOT:
- CMP DFLAG,0
- JZ NODFIX
- MOV AL,'.'
- STOSB
- NODFIX:
- SUB AL,AL
- STOSB
- CMP DFLAG,0
- JZ NODATE
- CMP DTAFLAG,0
- JNZ NSDATE
- CALL GCDATE
- MOV SI,OFFSET (FILNAME+2)
- JMP GSDATE
- NSDATE:
- MOV SI,OFFSET FILNAME
- CALL GTDATE
- GSDATE:
- MOV MYDATE,DX
- CMP DOTFLAG,0
- JZ SNODATE
- CMP EXTFLAG,0
- JNZ NSDAT2
- CALL GCDATE
- JMP GSDAT2
- NSDAT2:
- CALL GTDATE
- GSDAT2:
- MOV MYDAT2,DX
- SNODATE:
- MOV DI,OFFSET FILNAME
- MOV AX,'.*'
- STOSW
- SUB AH,AH
- STOSW
- NODATE:
- MOV DI,OFFSET PATNAME
- XOR AL,AL ; search directory for the zero at the
- CLD ; end of PATNAME
- MOV CX,64 ; max. length of scan for 0
- REPNZ SCASB
- MOV BX,DI
- DEC BX ; DS:BX points to the end of PATNAME
- MOV DX,0 ; tell search directory this is first
- CALL SCHDIR ; now do the recursive search
- ABSXIT:
- MOV AH,76
- MOV AL,AFLAG
- INT 21H ; all done return to DOS
- WHEREIS ENDP
- PAGE
- ;----------------------------------------------------------------;
- ; This procedure searches all the files in the current directory;
- ;looking for a match. It also prints the full name of each match ;
- ; ;
- ; DS:BX pointer to end of current path name. ;
- ; DS:DX old disk transfer area (DTA). ;
- ; ;
- ; READS: disk transfer area ;
- ; WRITES: disk transfer area ;
- ; CALLS: BLDNAME,GFMATCH, ;
- ; WMENAME,GNMATCH, ;
- ; BLDSNAME,SCHSDIR ;
- ;----------------------------------------------------------------;
- SCHDIR PROC NEAR
- PUSH SI ; need to restore on exit
- PUSH DX
- CALL BLDNAME ; build the absolute search name
- CALL GFMATCH ; see if there is a match there
- FINNEXFILE:
- JC NMATCH ; no match check sub directories
- CALL WMENAME ; write name of match
- CALL GNMATCH ; find the next match
- JMP FINNEXFILE ; look for next matching name
- NMATCH:
- POP DX ; restore DTA
- PUSH DX
- CALL BLDSNAME ; search for all directories
- CALL GFMATCH ; get first entry
- MOV SI,DX ; put address of DTA in SI
- FINNEXDIRECTORY:
- JC NMORMATCHES ; there are no entries
- TEST [SI].ATTRIBUTE,10H ; is it a directory ?
- JZ ISNOTADIR ; no, then find the next match
- CMP [SI].NAMFOUND,'.' ; is this a . or .. directory?
- JE ISNOTADIR ; yes then skip to next directory
- CALL SCHSDIR ; search the sub dir
- PUSH AX ; now reset the DTA
- MOV AH,1AH
- INT 21H
- POP AX
- ISNOTADIR:
- CALL GNMATCH ; then find the next match
- JMP FINNEXDIRECTORY ; and go back
- NMORMATCHES:
- POP DX
- POP SI
- RET
- SCHDIR ENDP
- PAGE
- ;---------------------------------------------------------------;
- ; This procedure searches the sub dir whose name is in the DTA ;
- ; ;
- ; DS:BX end of current pathname ;
- ; DS:[DX].NAMFOUND name of sub dir to search ;
- ; ;
- ; READS: PATNAME ;
- ; WRITES: PATNAME ;
- ; CALLS: SCHDIR ;
- ;---------------------------------------------------------------;
- SCHSDIR PROC NEAR
- PUSH DI
- PUSH SI
- PUSH AX
- PUSH BX
- CLD ; set for increment
- MOV SI,DX ; put the address of DTA in SI
- ADD SI,OFFSET NAMFOUND ; set to start of sub dir name
- MOV DI,BX ; DS:DI - 0 at end of path name
- COPLOOP:
- LODSB ; copy one character
- STOSB
- OR AL,AL ; was it a zero
- JNZ COPLOOP ; no, keep copying
- MOV BX,DI ; set BX to end of new pathname
- STD ; set flag for decrement
- STOSB ; store a 0 at end of string
- MOV AL,'\'
- STOSB ; place a \ at end of pathname
- CALL SCHDIR ; search this new path
- POP BX ; restore the old end-of-path
- MOV BYTE PTR [BX],0 ; and store a zero here
- POP AX
- POP SI
- POP DI
- RET
- SCHSDIR ENDP
- PAGE
- ;---------------------------------------------------------------;
- ; This procedure prints the matched name after the path name ;
- ; ;
- ; DS:DX pointer to current DTA ;
- ; ;
- ; READS: PATNAME,NAMFOUND (in DTA) ;
- ; CALLS: WRSTR,CRLF ;
- ;---------------------------------------------------------------;
- WMENAME PROC NEAR
- PUSH AX
- PUSH DX
- PUSH DX
- MOV AL,OPFLAG
- OR AL,MYATTR
- JZ NOCHO
- XCHG BX,DX
- MOV AL,[BX].ATTRIBUTE
- XCHG BX,DX
- TEST BYTE PTR OPFLAG,XOPT
- JZ NOXACT
- CMP AL,MYATTR
- JZ NOCHO
- JMP NOWRT
- NOXACT:
- TEST BYTE PTR OPFLAG,NOPT
- JZ NONORM
- TEST AL,18H
- JZ NOW1
- JMP NOWRT
- NOW1:
- TEST BYTE PTR MYATTR,0FFH
- JZ NOCHO
- NONORM:
- TEST AL,MYATTR
- JNZ NOCHO
- JMP NOWRT
- NOCHO:
- CMP DFLAG,0
- JZ NOCHD
- XCHG BX,DX
- MOV AX,[BX].DATE
- XCHG BX,DX
- TEST1: TEST BYTE PTR DFLAG,LOPT
- JZ TEST2
- CMP DOTFLAG,0
- JZ TEST1A
- CMP AX,MYDAT2
- JNA TEST2
- TEST1A: CMP AX,MYDATE
- JB NOCHD
- TEST2: TEST BYTE PTR DFLAG,EOPT
- JZ TEST4
- CMP DOTFLAG,0
- JZ TEST2A
- CMP AX,MYDAT2
- JZ NOCHD
- TEST2A: CMP AX,MYDATE
- JZ NOCHD
- TEST4: TEST BYTE PTR DFLAG,GOPT
- JZ TEST8
- CMP DOTFLAG,0
- JZ TEST4A
- CMP AX,MYDAT2
- JNB TEST8
- TEST4A: CMP AX,MYDATE
- JA NOCHD
- TEST8:
- JMP SHORT NOWRT
- NOCHD:
- POP DX
- ADD DX,OFFSET NAMFOUND
- PUSH DX
- XCHG BX,DX
- CMP BYTE PTR [BX],'.'
- XCHG BX,DX
- JZ NOWRT
- MOV DX,PATADR
- MOV AL,[BX] ; save char at end of path
- MOV BYTE PTR [BX],0 ; set for end of string
- CALL WRSTR
- MOV [BX],AL ; restore character
- POP DX ; recover old pointer
- PUSH DX
- CALL WRSTR
- CALL CRLF
- MOV AFLAG,0
- NOWRT: POP DX
- POP DX
- POP AX
- RET
- WMENAME ENDP
- PAGE
- ;---------------------------------------------------------------;
- ; This procedure builds an absolute search name from PATNAME ;
- ; followed by FILNAME ;
- ; ;
- ; READS: FILNAME ;
- ; CALLS: BUILD to build the name ;
- ;---------------------------------------------------------------;
- BLDNAME PROC NEAR
- PUSH SI
- MOV SI,OFFSET FILNAME
- CALL BUILD
- POP SI
- RET
- BLDNAME ENDP
- BLDSNAME PROC NEAR
- PUSH SI
- MOV SI,OFFSET STANAME
- CALL BUILD
- POP SI
- RET
- BLDSNAME ENDP
- PAGE
- ;---------------------------------------------------------------;
- ; This procedure appends the string at DS:SI to PATNAME in ;
- ; PATNAME. It knows where the PATNAME ends from knowing how ;
- ; long PATNAME is. ;
- ; ;
- ; DS:SI name of file ;
- ; DS:BX end of PATNAME ;
- ; ;
- ; READS: DS:SI ;
- ; WRITES: PATNAME ;
- ;---------------------------------------------------------------;
- BUILD PROC NEAR
- PUSH AX
- PUSH DI
- MOV DI,BX
- CLD ; set for increment
- COPNAME:
- LODSB
- STOSB ; copy a character of name
- OR AL,AL ; end of string yet?
- JNZ COPNAME ; no keep copying
- POP DI
- POP AX
- RET
- BUILD ENDP
- PAGE
- ;------------------------------------------------------------------;
- ; This procedure finds the first match between the name given by ;
- ; DS:DX and the directory entries found in the directory PATNAME ;
- ; ;
- ; DS:DX pointer to current DTA ;
- ;RETURNS: ;
- ; CF 0 a match was found ;
- ; 1 no match found ;
- ; AX error code returned: ;
- ; 2 file not found ;
- ; 18 no more files ;
- ; DS:DX pointer to new DTA ;
- ; ;
- ; READS: PATNAME ;
- ; WRITES: DTAREAS ;
- ;------------------------------------------------------------------;
- GFMATCH PROC NEAR
- PUSH CX
- CMP DX,0 ; first one?
- JA ALLOCATE ; no, then allocate space
- MOV DX,OFFSET DTAREAS-TYPE DTA
- ALLOCATE:
- ADD DX,TYPE DTA ; no then allocate room for new DTA
- MOV CX,1FH ; search attribute for files and sdirs.
- MOV AH,1AH ; set DTA
- INT 21H
- PUSH DX ; need DX for address of search name
- MOV DX,OFFSET PATNAME
- MOV AH,4EH ; call for find first match
- INT 21H
- POP DX
- POP CX
- RET ; return with carry flag info
- GFMATCH ENDP
- PAGE
- ;---------------------------------------------------------------;
- ; This procedure is much like get first match. ;
- ; ;
- ; RETURNS ;
- ; CF 0 a match was found ;
- ; 1 no match found ;
- ; AX error code returned: ;
- ; 2 file not found ;
- ; 18 no more files ;
- ; ;
- ; READS: PATNAME ;
- ; WRITES: DTAREAS ;
- ;---------------------------------------------------------------;
- GNMATCH PROC NEAR
- PUSH CX
- PUSH DX
- MOV DX,OFFSET PATNAME
- MOV CX,1FH ; attribute for files and directories
- MOV AH,4FH ; call for find next match
- INT 21H
- POP DX
- POP CX
- RET ; return with carry flag intact
- GNMATCH ENDP
- PAGE
- ;---------------------------------------------------------------;
- ; This proc send a crlf to the screen ;
- ;---------------------------------------------------------------;
- CRLF PROC NEAR
- PUSH AX
- PUSH DX
- MOV AH,2
- MOV DL,CR
- INT 21H
- MOV DL,LF
- INT 21H
- CMP LINECT,0
- JZ XCRLF
- DEC CURLIN
- JNZ XCRLF
- MOV AH,LINECT
- MOV CURLIN,AH
- MOV AH,7
- INT 21H
- CMP AL,3
- JNZ L0366
- JMP ABSXIT
- L0366: AND AL,5FH
- CMP AL,'S'
- JNZ XCRLF
- POP DX
- PUSH DX
- JMP SHELL
- XCRLF:
- POP DX
- POP AX
- RET
- CRLF ENDP
- ;---------------------------------------------------------------;
- ; This proc writes the ASCIIZ string at ;
- ; DS:DX address of ASCIIZ ;
- ;---------------------------------------------------------------;
- WRSTR PROC NEAR
- PUSH AX
- PUSH DX
- PUSH SI
- CLD ; set for increment
- MOV SI,DX ; set pointer to string
- MOV AH,2
- LODSB
- WRITSTRINLOOP:
- MOV DL,AL
- INT 21H ; write the char
- LODSB
- OR AL,AL ; end of string?
- JNZ WRITSTRINLOOP
- POP SI
- POP DX
- POP AX
- RET
- WRSTR ENDP
-
- GCDATE: MOV AH,42
- INT 21H
- SUB CX,1980
- MOV AX,CX
- MOV CL,4
- SHL AX,CL
- MOV CL,DH
- OR AX,CX
- MOV CL,5
- SHL AX,CL
- SUB DH,DH
- OR DX,AX
- RET
- GTDATE: CALL GETVAL
- OR DX,DX
- JZ BADDAT
- CMP DX,13
- JNC BADDAT
- MOV CL,5
- ROL DX,CL
- MOV BX,DX
- CALL GETVAL
- OR DX,DX
- JZ BADDAT
- CMP DX,32
- JNC BADDAT
- OR BX,DX
- CALL GETVAL
- CMP DX,100
- JNC NOADD19
- ADD DX,1900
- NOADD19:
- SUB DX,1980
- CMP DX,120
- JNC BADDAT
- MOV CL,9
- ROL DX,CL
- OR DX,BX
- RET
- BADDAT: MOV DX,OFFSET BDM1
- MOV AH,9
- INT 21H
- JMP ABSXIT
- BDM1 DB 'Bad date',13,10,'$'
- GETVAL: SUB DX,DX
- SUB AH,AH
- GV1: LODSB
- CMP AL,'.'
- JZ GVX
- CMP AL,'-'
- JZ GVX
- SUB AL,'0'
- CMP AL,10
- JNC GVEX
- MOV CX,DX
- ADD DX,DX
- ADD DX,DX
- ADD DX,CX
- ADD DX,DX
- ADD DX,AX
- JMP GV1
- GVEX: MOV DX,-1
- GVX: RET
- SHELL: PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DI
- PUSH BP
- MOV CX,BX
- MOV SI,OFFSET PATNAME
- MOV DI,OFFSET (CMDDTA+1)
- SUB CX,SI
- PUSH CX
- PUSH DX
- CALL SENDEM
- POP SI
- MOV CX,12
- CALL SENDEM
- MOV BYTE PTR [DI],CR
- MOV AX,12
- SUB AX,CX
- POP CX
- ADD AX,CX
- MOV CMDDTA,AL
- MOV AH,47
- INT 21H
- PUSH BX
- MOV STKPTR,SP
- MOV AX,CS
- MOV PARBLK+4,AX
- MOV PARBLK+8,AX
- MOV PARBLK+12,AX
- MOV DX,OFFSET MSG4
- MOV AH,9
- INT 21H
- MOV DX,OFFSET CMDBUF
- MOV AH,10
- INT 21H
- MOV DL,LF
- MOV AH,2
- INT 21H
- MOV AL,CMDDTA
- MOV CMDLIN,AL
- OR AL,AL
- JZ NOSETUP
- MOV SI,OFFSET PREFMSG
- MOV DI,OFFSET CMDLIN
- ADD AL,4
- STOSB
- MOVSW
- MOVSW
- NOSETUP:
- MOV AX,DS:[2CH]
- MOV DS,AX
- MOV SI,0
- MOV DI,OFFSET COMSPEC
- LOOP1: PUSH DI
- PUSH SI
- MOV CX,4
- REP CMPSW
- JZ GOTSPEC
- POP SI
- POP DI
- LOOP2: LODSB
- OR AL,AL
- JNZ LOOP2
- MOV AL,[SI]
- OR AL,AL
- JNZ LOOP1
- MOV AX,CS
- MOV DS,AX
- MOV DX,OFFSET MSG2
- MOV AH,9
- INT 21H
- INT 20H
- GOTSPEC:
- POP DI
- POP DI
- MOV DX,SI
- MOV BX,OFFSET PARBLK
- MOV AX,4B00H
- INT 21H
- MOV AX,CS
- MOV SS,AX
- MOV SP,CS:STKPTR
- MOV DS,AX
- MOV ES,AX
- POP DX
- MOV AH,26
- INT 21H
- POP BP
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- POP AX
- JMP XCRLF
- SENDEM: LODSB
- OR AL,AL
- JZ NOSEND
- STOSB
- LOOP SENDEM
- NOSEND: RET
- LINECT DB 0
- CURLIN DB 0
- STKPTR DW ?
- MSG1 DB 'Unable to release memory.$'
- COMSPEC DB 'COMSPEC='
- MSG2 DB 'COMSPEC must be set$'
- PARBLK DW 0,CMDLIN,?,FCB1,?,FCB2,?
- CMDLIN DB 0,CR,0
- CMDBUF DB 128
- CMDDTA DB 0,CR,0,128 DUP(?)
- PREFMSG DB ' /C '
- MSG4 DB 13,'Enter command for shell operation.',CR,LF,'*$'
- FCB1 DB 0,11 DUP('?'),25 DUP(0)
- FCB2 DB 0,11 DUP(' '),25 DUP (0)
- MYDATE DW 0
- MYDAT2 DW 0
- MYATTR DB 0
- OPFLAG DB 0
- DFLAG DB 0
- PATADR DW ?
- DOTFLAG DB 0
- DTAFLAG DB 0
- EXTFLAG DB 0
- AFLAG DB 1
- STANAME DB '*.*',0
- PATNAME DB ' :\',0
- DB 80 DUP (0) ; space for 64 char path name
- ; and 13 char file name
- ; or 2 8 char dates
- FILNAME DB 19 DUP (0) ; save room for full DOS name
- DTAREAS LABEL BYTE ; this starts at the end of the whereis
- LOCAL_STACK EQU DTAREAS+2048
- CODSEG ENDS
- END WHEREIS
- LABEL BYTE ; this starts at the end of